import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

class Test15 extends StatefulWidget {
  @override
  _Test15State createState() => _Test15State();
}

class _Test15State extends State<Test15> with SingleTickerProviderStateMixin {
  final List<IconData> list = [
    //菜单的icon
    Icons.home,
    Icons.new_releases,
    Icons.notifications,
    Icons.settings,
    Icons.menu,
  ];
  AnimationController _animationController;
  IconData lastUpIcon = Icons.notifications;

  @override
  void initState() {
    super.initState();
    _animationController =
        AnimationController(duration: Duration(milliseconds: 200), vsync: this);
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Flow(
        delegate: MyFlowDelegate(_animationController),
        children: list
            .map<Widget>((IconData iconData) => transformMenu(iconData))
            .toList(),
      ),
    );
  }

  Widget transformMenu(IconData e) {
    double buttonWidth =
        MediaQuery.of(context).size.width * 2 / (list.length * 3);
    return Padding(
      padding: EdgeInsets.symmetric(vertical: 8.0),
      child: RawMaterialButton(
        fillColor: lastUpIcon == e ? Colors.amber[700] : Colors.blue,
        splashColor: Colors.amber[100],
        shape: CircleBorder(),
        constraints: BoxConstraints.tight(Size(buttonWidth, buttonWidth)),
        onPressed: () {
          updateMenu(e);
        },
        child: Icon(e, size: 30, color: Colors.white),
      ),
    );
  }

  void updateMenu(IconData e) {
    if (lastUpIcon != Icons.menu) {}
    setState(() {
      lastUpIcon = e;
      _animationController.status == AnimationStatus.completed
          ? _animationController.reverse()
          : _animationController.forward();
    });
  }
}

class MyFlowDelegate extends FlowDelegate {
  final Animation _animationController;

  MyFlowDelegate(this._animationController)
      : super(repaint: _animationController);

  @override
  void paintChildren(FlowPaintingContext context) {
    double width = 50.0;
    double height = 50.0;
    for (int i = 0; i < context.childCount; ++i) {
      double x = context.getChildSize(i).width * i * _animationController.value;
      context.paintChild(i, transform: Matrix4.translationValues(x, height, 0));
    }
  }

  @override
  bool shouldRepaint(covariant MyFlowDelegate oldDelegate) {
    return _animationController != oldDelegate._animationController;
  }
}
